#!/bin/sh
#
# This script is used for adding a user to run the MySQL server in a chroot jail.
#
# It builds the chroot jailed system using SuSE packages thorugh 'zypper'.
# The advantage of using packages to build the jail is that it becomes much easier
# to apply patches to the user chroot jail in the future.
# Once the jail is built 'aide' will be run to initialize a database for the
# user. This database can be used (in the future) to determine if any of the files
# in the jail have been change.
#
# Before applying patches, 'aide' is run on the jail to see if anything
# has changed since the last time patches were installed.. After the patches are
# applied 'aide' is again run on the jail to build the database for the next
# itteration of patch applications.
#
# Note:
# With the base systen (e.g., from create_chroot) and X11 the root directory is
# about 159 MB. With all packages except MySQL the chroot directory is about 640 MB.
# With just the base system and MySQL the chroot directory is 132 MB.
#
# Note:
# Users on the same machine communicate through the 'mysql.sock' file in '/var/run/mysql'
# (by default). This file appears to be created by the server on startup. So,
# any client that wants to use the database instance that is located here should
# have a "hard link" created from this file in the server's root to this file in the
# client's directory, e.g...
# ln /home/chroot/mysqld/var/run/mysql/mysql.sock  /home/chroot/mysqluser/var/run/mysql/mysql.sock 
#
#
# enchroot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# enchroot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with enchroot. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (c) 2010 charles@kollar.com
#

#
# Global configuraiton/options are set in this file...
. /usr/local/etc/enchroot.conf

##
## You should not have to change anything below this!
##

CHROOT_USERNAME=$1

JAILPATH=$HOME_CHROOT/$CHROOT_USERNAME

DATADIR="/var/lib/mysql"

USERAIDEDIR=$AIDEDIR/$CHROOT_USERNAME

MYSQL_HOME=/home/mysql/$CHROOT_USERNAME

if ( id $CHROOT_USERNAME > /dev/null 2>&1 ) ; then {
  echo "OK. User $CHROOT_USERNAME exists..."
} ; else {
  echo "User $CHROOT_USERNAME should first be created with the 'create_chroot' script before running this script!"
  exit 1
}
fi

echo ""
echo "Installing MySQL server..."
# 'net-tools' is needed for /bin/hostname' used when creating databases from the install script...
zypper --root $JAILPATH install --no-recommends --auto-agree-with-licenses --type package net-tools mysql

# copy the config file for this user's instance...
mkdir -p $JAILPATH/etc
cp $MYSQL_HOME/my.cnf $JAILPATH/etc
chown $CHROOT_USERNAME:$CHROOT_USERNAME $JAILPATH/etc/my.cnf
chmod 640 $JAILPATH/etc/my.cnf

# When installing InnoDB you must create directories yourself,
# InnoDB does not install them. This should be the 'innodb_data_home_dir'
# from the '/home/mysql/$CHROOT_USERNAME/my.cnf' script.

# '$SERVERDATA_DIR' is the file system that is mounted to '${JAILPATH}${DATADIR}'
SERVERDATA_DIR=${MYSQL_HOME}/data
INNODB_DIR=$SERVERDATA_DIR/innodb
if ! [ -d $INNODB_DIR ] ; then
  echo "Creating ${INNODB_DIR}..."
  # this will also make $SERVERDATA_DIR if it does not exist...
  mkdir -p $INNODB_DIR
fi
chown -R $CHROOT_USERNAME:$CHROOT_USERNAME ${SERVERDATA_DIR}
chmod 750 ${SERVERDATA_DIR}
chmod 750 ${INNODB_DIR}

# set the jail up to mount the directory that the data is on...
# e.g. this is the mountpoint of $DATA_DIR in the jail...
if ! [ -d "${JAILPATH}${DATADIR}" ] ; then
  echo "Creating '${JAILPATH}${DATADIR}'..."
  mkdir -p ${JAILPATH}${DATADIR}
fi
chown $CHROOT_USERNAME:$CHROOT_USERNAME $JAILPATH${DATADIR}
chmod 750 ${JAILPATH}${DATADIR}

# set the user up to be able to mount the jail directory...
echo "Modifying /etc/sudoers..."
# create_chroot will already have put in a line into sudoers to allow mounting of /dev.
echo "$CHROOT_USERNAME ALL=NOPASSWD: `which mount` -o bind /proc $JAILPATH/proc" >> /etc/sudoers
echo "$CHROOT_USERNAME ALL=NOPASSWD: `which mount` -o bind $SERVERDATA_DIR ${JAILPATH}${DATADIR}" >> /etc/sudoers
echo "Changing the ownership of the database files..."
# mount it now, and change the ownership of the files to our user...
mount -o bind $SERVERDATA_DIR ${JAILPATH}${DATADIR}
chown -R $CHROOT_USERNAME:$CHROOT_USERNAME ${JAILPATH}${DATADIR}

if ! [ -d ${JAILPATH}/var/run/mysql ] ; then
  echo "Creating ${JAILPATH}/var/run/mysql..."
  mkdir -p ${JAILPATH}/var/run/mysql
fi
chown -R $CHROOT_USERNAME:$CHROOT_USERNAME ${JAILPATH}/var/run/mysql

if ! [ -d ${JAILPATH}/var/log/mysql ] ; then
  echo "Creating ${JAILPATH}/var/log/mysql..."
  mkdir -p ${JAILPATH}/var/log/mysql
fi
chown -R $CHROOT_USERNAME:$CHROOT_USERNAME ${JAILPATH}/var/log/mysql

chmod 177 ${JAILPATH}/tmp

# instead of a shell we need a script 'mysql_shell' that mounts the database directory on the
# appropriate chroot mount point, and then starts the server. 
passwdline=`grep "^${CHROOT_USERNAME}:.*" /etc/passwd | awk -F : '{print $1 ":" $2 ":" $3 ":" $4 ":" $5 ":" $6 ":/usr/local/bin/mysql_shell"}'`
PASSWDTMP=/tmp/passwd.$$
grep -v "^${CHROOT_USERNAME}:.*" /etc/passwd > $PASSWDTMP
echo $passwdline >> $PASSWDTMP
cp $PASSWDTMP /etc/passwd
rm $PASSWDTMP

#
# the user 'mysql' is hardwired into the initialization scripts.
# Here we change that user to the chroot_username
sed "s/mysql_daemon_user=mysql/mysql_daemon_user=$CHROOT_USERNAME/" $JAILPATH/etc/init.d/mysql | sed "s/mysql_daemon_group=mysql/mysql_daemon_group=$CHROOT_USERNAME/" > $MYSQL_HOME/init.d_mysql

# Now fix a but in the startup script where the 'mysql' user is hardwired in...
sed 's/chown mysql:mysql/chown $mysql_daemon_user:$mysql_daemon_group/g' $MYSQL_HOME/init.d_mysql > $JAILPATH/etc/init.d/mysql

# don't really need to do this unless the user has added something above...
echo ""
echo "Creating user's aide database..."
aide --init --config=$AIDEDIR/$CHROOT_USERNAME/aide.conf

SECURE_INSTALLATION=/usr/bin/mysql_secure_installation
echo
echo "Running $SECURE_INSTALLATION ..."
echo "Note: the current root password is the empty string, It should be set to something"
echo "that is about 10 characters long, and a mixture of upper/lower case and numbers."
echo "Otherwise, just take the defaults."
chroot $JAILPATH $SECURE_INSTALLATION
